//
//  YCAlert.m
//  YCAlert
//
//  Created by Stephan Cleaves on 4/2/07.
//  Copyright 2007 Yellow Camp Software. All rights reserved.
//
//  Freely licensed under the MIT License. See included license file for details.
//

#import "YCAlert.h"

static unsigned int WindowCount;
static NSPoint LastTopLeft;

@interface YCAlert (Private)
- (NSButton *)createButtonWithTitle:(NSString *)title frame:(NSRect)frameRect;
- (void)adjustSizeAndPositionOfButtons;
@end

@implementation YCAlert

+ (void)initialize
{
    LastTopLeft = NSZeroPoint;
}

- (id)init
{
    if ( ( self = [super init] ) != nil ) {
        buttons = [[NSMutableArray alloc] initWithObjects:[NSNull null], [NSNull null],
            [NSNull null], nil];
        
        panel = [[NSPanel alloc] initWithContentRect:NSMakeRect( 0, 0, 450, 133 )
            styleMask:NSTitledWindowMask
            backing:NSBackingStoreBuffered defer:NO];
        [panel setFrameOrigin:NSMakePoint( 500, 500 )];
        [panel setContentMinSize:NSMakeSize( 450, 133 )];
        
        imageView = [[NSImageView alloc] initWithFrame:NSMakeRect( 20, 60, 64, 64 )];
        [imageView setImage:[[NSApplication sharedApplication] applicationIconImage]];
        [imageView setAutoresizingMask:( NSViewMaxXMargin | NSViewMinYMargin )];
        [[panel contentView] addSubview:imageView];
        
        messageField = [[NSTextField alloc] initWithFrame:NSMakeRect( 106, 96, 327, 17 )];
        [messageField setAutoresizingMask:( NSViewWidthSizable | NSViewMinYMargin )];
        [messageField setFont:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]]];
        [messageField setEditable:NO];
        [messageField setSelectable:NO];
        [messageField setBordered:NO];
        [messageField setDrawsBackground:NO];
        [[panel contentView] addSubview:messageField];
        
        informativeField = [[NSTextField alloc] initWithFrame:NSMakeRect( 106, 60, 328, 28 )];
        [informativeField setAutoresizingMask:( NSViewWidthSizable | NSViewHeightSizable )];
        [informativeField setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
        [informativeField setEditable:NO];
        [informativeField setSelectable:NO];
        [informativeField setBordered:NO];
        [informativeField setDrawsBackground:NO];
        [[panel contentView] addSubview:informativeField];
    }
    
    return self;
}

- (void)dealloc
{
    [buttons release];
    [imageView release];
    [messageField release];
    [informativeField release];
    [panel release];
    
    [super dealloc];
}

- (NSButton *)addPrimaryButtonWithTitle:(NSString *)buttonTitle
{
    if ( !buttonTitle ) {
        return nil;
    } else {
        if ( [buttons objectAtIndex:0] != [NSNull null] ) {
            [(NSButton *)[buttons objectAtIndex:0] removeFromSuperviewWithoutNeedingDisplay];
        }
    }
    
    NSButton *button = [self createButtonWithTitle:buttonTitle frame:NSMakeRect( 354, 12, 82, 32 )];
    [buttons replaceObjectAtIndex:0 withObject:button];
    
    [button setAutoresizingMask:( NSViewMinXMargin | NSViewMaxYMargin )];
    [button setKeyEquivalent:@"\r"];
    
    [[panel contentView] addSubview:button];
    [self adjustSizeAndPositionOfButtons];
    
    return [button autorelease];
}

- (NSButton *)addAlternateButtonWithTitle:(NSString *)buttonTitle
{
    if ( !buttonTitle ) {
        return nil;
    } else {
        if ( [buttons objectAtIndex:1] != [NSNull null] ) {
            [(NSButton *)[buttons objectAtIndex:1] removeFromSuperviewWithoutNeedingDisplay];
        }
    }
    
    NSButton *button = [self createButtonWithTitle:buttonTitle frame:NSMakeRect( 272, 12, 82 ,32 )];
    [buttons replaceObjectAtIndex:1 withObject:button];

    [button setAutoresizingMask:( NSViewMinXMargin | NSViewMaxYMargin )];
    
    [[panel contentView] addSubview:button];        
    [self adjustSizeAndPositionOfButtons];
    
    return [button autorelease];
}

- (NSButton *)addOtherButtonWithTitle:(NSString *)buttonTitle
{
    if ( !buttonTitle ) {
        return nil;
    } else {
        if ( [buttons objectAtIndex:2] != [NSNull null] ) {
            [(NSButton *)[buttons objectAtIndex:2] removeFromSuperviewWithoutNeedingDisplay];
        }
    }
    
    NSButton *button = [self createButtonWithTitle:buttonTitle frame:NSMakeRect( 103, 12, 82, 32 )];
    [buttons replaceObjectAtIndex:2 withObject:button];
    
    [button setAutoresizingMask:( NSViewMaxXMargin | NSViewMaxYMargin )];
    
    [[panel contentView] addSubview:button];
    [self adjustSizeAndPositionOfButtons];
    
    return [button autorelease];
}

- (void)beginModelessAlertWithDelegate:(id)delegate selector:(SEL)didEndSelector 
    contextInfo:(void *)contextInfo
{

    
    _delegate = delegate;
    _didEndSelector = didEndSelector;
    _contextInfo = contextInfo;
    
    if ( NSEqualPoints( LastTopLeft, NSZeroPoint ) || WindowCount == 0 ) {
        NSRect screenFrame = ( [NSApp keyWindow] ? [[[NSApp keyWindow] screen] visibleFrame] : 
            [[NSScreen mainScreen] visibleFrame] );
        NSRect panelFrame = [panel frame];
        panelFrame.origin.x = screenFrame.origin.x + NSWidth( screenFrame ) / 2 - NSWidth( panelFrame ) / 2;
        panelFrame.origin.y = screenFrame.origin.y + NSHeight( screenFrame ) / 2 + NSHeight( panelFrame ) / 2;
        [panel setFrame:panelFrame display:NO];
        LastTopLeft = NSZeroPoint;
    }
    
    LastTopLeft = [panel cascadeTopLeftFromPoint:LastTopLeft];
    
    [panel makeKeyAndOrderFront:self];
    WindowCount++;
}

- (void)buttonPressed:(id)sender
{
    int returnCode = ( [sender isEqual:[buttons objectAtIndex:0]] ? YCAlertPrimaryReturn :
        ( [sender isEqual:[buttons objectAtIndex:1]] ? YCAlertAlternateReturn :
        YCAlertOtherReturn ) );

    [panel close];
    WindowCount--;
    
    [[self retain] autorelease];
    
    if ( [_delegate respondsToSelector:_didEndSelector] ) {
        objc_msgSend( _delegate, _didEndSelector, self, returnCode, _contextInfo );
    }
}

- (void)setInformativeText:(NSString *)informativeText
{
    NSRect fieldFrame = [informativeField frame];
    NSSize newSize, origSize = [informativeField frame].size, 
        panelSize = [[panel contentView] frame].size;
    
    [informativeField setStringValue:informativeText];
    
    fieldFrame.size.height = 10000;
    newSize = [[informativeField cell] cellSizeForBounds:fieldFrame];
    
    if ( newSize.height > origSize.height ) {
        [informativeField setFrameOrigin:NSMakePoint( fieldFrame.origin.x, 
            fieldFrame.origin.y - ( newSize.height - origSize.height ) )];
        [informativeField setFrameSize:NSMakeSize( fieldFrame.size.width, newSize.height )];
        panelSize.height += newSize.height - origSize.height;
        [panel setContentSize:panelSize];
    }
}

- (NSString *)informativeText
{
    return [informativeField stringValue];
}

- (void)setMessageText:(NSString *)messageText
{
    [messageField setStringValue:messageText];
}

- (NSString *)messageText
{
    return [messageField stringValue];
}

- (void)setTitle:(NSString *)title
{
    [panel setTitle:title];
}

- (NSString *)title
{
    return [panel title];
}

@end

@implementation YCAlert (Private)

- (NSButton *)createButtonWithTitle:(NSString *)title frame:(NSRect)frameRect
{
    NSButton *button = [[NSButton alloc] initWithFrame:frameRect];
    NSRect buttonFrame;
    
    [button setAutoresizingMask:( NSViewMinXMargin | NSViewMaxYMargin )];
    [button setBezelStyle:NSRoundedBezelStyle];
    [button setTitle:title];
    [button setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
    [button setTarget:self];
    [button setAction:@selector( buttonPressed: )];

    [button sizeToFit];
    buttonFrame = [button frame];
    buttonFrame.size.width += 10;
    [button setFrame:buttonFrame];
    
    return button;
}

- (void)adjustSizeAndPositionOfButtons
{
    int buttonXPos = [panel frame].size.width - 14;
    NSRect buttonFrame;
    
    if ( [buttons objectAtIndex:0] != [NSNull null] && [buttons objectAtIndex:1] != [NSNull null] ) {
        NSButton *primaryButton = [buttons objectAtIndex:0];
        NSButton *alternateButton = [buttons objectAtIndex:1];
        float buttonWidth = fmax( [primaryButton frame].size.width,
            [alternateButton frame].size.width );
        
        buttonFrame = [primaryButton frame];
        buttonFrame.size.width = buttonWidth;
        buttonXPos -= buttonWidth;
        buttonFrame.origin.x = buttonXPos;
        [primaryButton setFrame:buttonFrame];
        
        buttonFrame = [alternateButton frame];
        buttonFrame.size.width = buttonWidth;
        buttonXPos -= buttonWidth;
        buttonFrame.origin.x = buttonXPos;
        [alternateButton setFrame:buttonFrame];
    }
    
    if ( [buttons objectAtIndex:2] != [NSNull null] ) {
        NSButton *otherButton = [buttons objectAtIndex:2];

        buttonFrame = [otherButton frame];
        if ( buttonXPos < NSMaxX( buttonFrame ) ) {
            NSRect panelFrame = [panel frame];
            panelFrame.size.width += NSMaxX( buttonFrame ) - buttonXPos;
            [panel setFrame:panelFrame display:NO];
        }
    }
}

@end